/**
 * Created by thomas on 27/01/14.
 */

var InfoWindow = (function () {

    /**
     * 设置默认值
     * @param options
     * @param defaultOptions
     * @returns {{}}
     */
    function defaultValue(options, defaultOptions) {
        var newOptions = {}, option;
        for (option in options) {
            newOptions[option] = options[option];
        }
        for (option in defaultOptions) {
            if (newOptions[option] === undefined) {
                newOptions[option] = defaultOptions[option];
            }
        }
        return newOptions;
    }

    /**
     * 创建InfoWindow类
     * @param {Cesium.Viewer} cesiumViewer Cesium viewer
     * @param {Object} option 设置 offset偏移位置
     * @private
     */
    function _(cesiumViewer, option) {
        this._option = option || {offset:{x:0, y:0}};
        //创建容器
        var div = document.createElement('div');
        div.className = 'mapInfoWindow';
        this._div = div;
        
        var infoPanel = document.createElement('div');
        infoPanel.className = 'info-panel';
        var infoHeader = document.createElement('div');
        infoHeader.className = 'info-header';
        var infoHeaderClose = document.createElement('span');
        infoHeaderClose.className = 'close';
        var infoContent = document.createElement('div');
        infoContent.className = 'info-content';
        var infoContentBorderOut = document.createElement('div');
        infoContentBorderOut.className = 'info-content-border-out';
        var infoContentBorderIn = document.createElement('div');
        infoContentBorderIn.className = 'info-content-border-in';
        var infoLineRing = document.createElement('div');
        infoLineRing.className = 'info-line';
        var infoLine = document.createElement('div');
        infoLine.className = 'info-line-ring';
        var infoPoint = document.createElement('div');
        var infoLineTop = document.createElement('div');
        infoLineTop.className = 'info-line-top';
        infoPoint.className = 'info-point';
        var infoPointRing = document.createElement('div');
        infoPointRing.className = 'info-point-ring';
        infoHeader.innerHTML = "普天德胜";

        infoPanel.appendChild(infoLineRing);
        infoPanel.appendChild(infoPointRing);
        infoPanel.appendChild(infoContentBorderOut);
        infoContentBorderOut.appendChild(infoContentBorderIn);
        infoContentBorderOut.appendChild(infoLineTop);
        infoContentBorderIn.appendChild(infoHeader);
        infoContentBorderIn.appendChild(infoContent);
        infoContentBorderIn.appendChild(infoHeaderClose);
        infoPanel.appendChild(infoLine);
        infoPanel.appendChild(infoPoint);

//        infoHeaderClose.onclick = function (e) {
//        	e.stopPropagation();
//            _self.setVisible(false);
//            if(_self.closeHandler) _self.closeHandler();
//        };

        div.appendChild(infoPanel);
        cesiumViewer.container.appendChild(div);

        this._isBinding = false;//是否绑定对象
        this._title = infoHeader;//标题
        this._content = infoContent;//内容信息
        this._close = infoHeaderClose;//是否关闭
        var _self = this;
        this._close.onclick = function (e) {//当点击关闭按钮
            e.stopPropagation();
            _self.setVisible(false);
            if(_self.closeHandler) _self.closeHandler();
        };
        this.setVisible(true);
        
        this._scratch = new Cesium.Cartesian2();
        this._scene = cesiumViewer.scene;
        this._isOccluded = undefined;
        this._viewer = cesiumViewer;
        this._position;
//        this._viewer.scene.preRender.addEventListener(this.update);
    };

    /**
     * 设置是否可见
     * @param visible
     */
    _.prototype.setVisible = function (visible) {
        this._div.style.display = visible ? 'block' : 'none';
        this._visible = visible;
    };

    /**
     * 设置信息内容
     * @param content
     */
    _.prototype.setContent = function (content) {
        if (typeof content === 'string') {
            this._content.innerHTML = content;
        }
        else if(typeof content === 'function'){
        	while (this._content.firstChild) {
                this._content.removeChild(this._content.firstChild);
            }
        	content(this._content);
        }
        else if(this.isDOM(content)) {
            while (this._content.firstChild) {
                this._content.removeChild(this._content.firstChild);
            }
            this._content.appendChild(content);
        }
    };

    /**
     * 设置标题
     * @param title
     */
    _.prototype.setTitle = function (title) {
        if (typeof title === 'string') {
            this._title.innerHTML = title;
        } 
        else if(this.isDOM(title)) {
            while (this._title.firstChild) {
                this._title.removeChild(this._title.firstChild);
            }
            this._title.appendChild(title);
        }
    };

    /**
     * 判断是否为dom对象
     * @param obj
     * @returns {*}
     */
    _.prototype.isDOM = function(obj){
    	return (typeof HTMLElement === 'object' ) ?
    			(obj instanceof HTMLElement) : (obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string');
    }

    /**
     * 根据经纬度设置位置
     * @param lng
     * @param lat
     * @param height
     */
    _.prototype.setPositionFromDegrees = function (lng, lat, height) {
        this._position = this._scene.globe.ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(lng, lat, height ? height : 0));
    };

    /**
     * 设置位置
     * @param position
     */
    _.prototype.setPosition = function (position) {
        this._position = position;
    };

    /**
     * 绑定对象
     * @param targetObject
     */
    _.prototype.bindTarget = function(targetObject) {
    	this._target = targetObject;
    	if (Cesium.defined(targetObject)) {
    		this._isBinding = true;
    		
//        	var primitiveId = this._target.primitive.id ? this._target.primitive.id : '';
//            if(typeof primitiveId === 'string'){
//            	var attributes = this._target.primitive['attributes'];
//            	this.setContent(attributes);
//            }
//            else if(typeof primitiveId === 'object'){
//            	var attributes = this._target.id['attributes'];
//            	this.setContent(attributes);
//            }
//            var infoContent = '<div class="attributes-content">';
//            if(attributes){
//            	for(var key in attributes){
//            		infoContent += '<div>' + key + ':' + attributes[key] + '</div>'
//            	}
//            	infoContent += '</div>';
//            	this._content.innerHTML = infoContent;
//            }

    	}
    	else {
    		this._isBinding = false;
    	}
    };

    /**
     * 设置对象
     * @param targetObject
     */
    _.prototype.setTarget = function(targetObject) {
    	this._target = targetObject;
    };

    /**
     * 在指定的经纬度位置显示信息
     * @param lng
     * @param lat
     * @param height
     * @param title
     * @param content
     */
    _.prototype.showAtFromDegrees = function (lng, lat, height, title, content) {
        this.setPositionFromDegrees(lng, lat, height);
        this.setTitle(title);
        this.setContent(content);
        this.setVisible(true);
    };

    /**
     * 在指定的位置显示信息
     * @param position
     * @param title
     * @param content
     */
    _.prototype.showAt = function (position, title, content) {
        this.setPosition(position);
        this.setTitle(title);
        this.setContent(content);
        this.setVisible(true);
    };

    /**
     * 隐藏
     */
    _.prototype.hide = function () {
        this.setVisible(false);
    };

    /**
     * 计算可视区域
     */
    _.prototype.computeVisible = function () {
    	if (!this._position) {
            return;
        }
        // Ellipsoid radii - WGS84 shown here
        var rX = 6378137.0;
        var rY = 6378137.0;
        var rZ = 6356752.3142451793;
        // Vector CV
        var cameraPosition = this._scene.camera.position;
        var cvX = cameraPosition.x / rX;
        var cvY = cameraPosition.y / rY;
        var cvZ = cameraPosition.z / rZ;

        var vhMagnitudeSquared = cvX * cvX + cvY * cvY + cvZ * cvZ - 1.0;

        // Target position, transformed to scaled space
        var position = this._position;
        var tX = position.x / rX;
        var tY = position.y / rY;
        var tZ = position.z / rZ;

        // Vector VT
        var vtX = tX - cvX;
        var vtY = tY - cvY;
        var vtZ = tZ - cvZ;
        var vtMagnitudeSquared = vtX * vtX + vtY * vtY + vtZ * vtZ;

        // VT dot VC is the inverse of VT dot CV
        var vtDotVc = -(vtX * cvX + vtY * cvY + vtZ * cvZ);

        // 是否遮蔽
        var isOccluded = vtDotVc > vhMagnitudeSquared &&
            vtDotVc * vtDotVc / vtMagnitudeSquared > vhMagnitudeSquared;

        if(this._isOccluded !== isOccluded){
            this._isOccluded = isOccluded;
            if (isOccluded) {
                if (this._visible) {
                    this._div.style.display = 'none';
                }
            }
            else {
                if (this._visible) {
                    this._div.style.display = '';
                }
            }
        }
    };

    /**
     * 更新渲染
     * @param context
     * @param frameState
     * @param commandList
     */
    _.prototype.update = function (context, frameState, commandList) {
        this.computeVisible();
        if (!this._visible) {
            return;
        }
        var isCesiumObj = false;
        if(Cesium.defined(this._target)){
//        	if(this._viewer.scene.primitives){
//        		isCesiumObj = this._viewer.scene.primitives.contains(this._target.primitive);
//        	}
//        	if(!isCesiumObj && this._viewer.entities){
//        		isCesiumObj = this._viewer.entities.contains(this._target.primitive) || (this._target.hasOwnProperty('id') && this._viewer.entities.contains(this._target.id));
//        	}
        	
        	isCesiumObj = this._target instanceof Cesium.Entity || this._target instanceof Cesium.Primitive || Cesium.Cesium3DTileFeature;
        }
        if(isCesiumObj){
        	if(this._isBinding){//绑定状态下，实时更新信息
            	var objectId = this._target.id;
            	if (this._target instanceof Cesium.Primitive) {//primitive model
            		var boundingSphere = this._target.primitive.boundingSphere;
                    var modelMatrix = this._target.primitive.modelMatrix;
                	if(Cesium.defined(boundingSphere)  && Cesium.defined(modelMatrix)){
                		this._position = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
                	}
                	var attributes = this._target.primitive['attributes'];
                 	this.setContent(attributes);
                }
                else if (this._target instanceof Cesium.Entity) {//entity
                    if (Cesium.defined(this._target.model)) {//model
//                        var boundingSphere = this._target.primitive.boundingSphere;
//                        var modelMatrix = this._target.primitive.modelMatrix;
//                        if(Cesium.defined(boundingSphere)  && Cesium.defined(modelMatrix)){
//                    		this._position = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
//                    	}
                    	if(this._target.position instanceof Cesium.ConstantPositionProperty){
                    		this._position = this._target.position.getValue(Cesium.JulianDate.now());
                    	}
                        var attributes = this._target['attributes'];
                     	this.setContent(attributes);
                    }
                    else if (Cesium.defined(objectId.polylineVolume)) {

                    }
                    else if (Cesium.defined(objectId.ellipsoid)) {

                    }
                    else if (Cesium.defined(objectId.billboard)) {
//                        var position = new Cesium.Cartesian3(objectId.position._value.x, objectId.position._value.y, objectId.position._value.z);
//                        var imgWidth = this._selectedObject.primitive.width;
                        //未计算出绘制圆半径
                    }
                }
        	}
        }
        else {
        	this._target = null;
        	this._title.innerHTML = '';
        	this._content.innerHTML = '';
        	this.setVisible(false);
        	this.closeHandler();
        	this._isBinding = false;
        }
        
        if (!this._position) {
            return;
        }

        // get the position on the globe as screen coordinates
        // coordinates with origin at the top left corner
        var coordinates = Cesium.SceneTransforms.wgs84ToWindowCoordinates(this._scene, this._position);
        if (coordinates) {
            var left = Math.round(coordinates.x - this._div.clientWidth / 2 + this._option.offset.x);
            var top = Math.round(coordinates.y - this._div.clientHeight + this._option.offset.y);
            var originalLeft = Number(String(this._div.style.left).replace('px', ''));
            var originalTop = Number(String(this._div.style.top).replace('px', ''));
            var tolerate = this._isBinding ? 0 : 3;
            if(Math.abs(left - originalLeft) > tolerate)
            	this._div.style.left = left + "px";
            if(Math.abs(top - originalTop) > tolerate)
            	this._div.style.top = Math.round(top) + "px";
        }
    };
    
//    _.prototype.update = function(){
//        if(this.computeVisible)this.computeVisible();
//        if (!this._visible || !this._position) {
//            return;
//        }
//        
//        if(this._target){
//        	var boundingSphere = this._target.primitive.boundingSphere;
//            var modelMatrix = this._target.primitive.modelMatrix;
//        	if(Cesium.defined(boundingSphere)  && Cesium.defined(modelMatrix)){
//        		this._position = Cesium.Matrix4.multiplyByPoint(modelMatrix, boundingSphere.center, new Cesium.Cartesian3());
//        	}
//        }
//        var canvasPosition = viewer.scene.cartesianToCanvasCoordinates(this._position, this._scratch);
//        if (Cesium.defined(canvasPosition)) {
//        	this._div.style.top = Math.floor(canvasPosition.y) -  this._div.offsetHeight + this._option.offset.y + 'px';
//        	this._div.style.left = Math.floor(canvasPosition.x) -  this._div.offsetWidth/2 + this._option.offset.x + 'px';
//        }
//    }

    _.prototype.destroy = function () {
//    	this._viewer.scene.preRender.addEventListener(this.update);
        this._div.parentNode.removeChild(this._div);
    };

    return _;
})();
